home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assemblers / cas.lha / das.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-15  |  13.7 KB  |  394 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef unsigned char byte;
  5. typedef unsigned int word;
  6.  
  7. byte Arg[3];
  8. word PC; byte Generating;
  9. byte Ref[0x4000], Hex[0x4000];
  10. #define ENTRY 0x80
  11. #define OP    0x40
  12. #define ARG   0x20
  13. #define LINKS 0x1f
  14.  
  15. word Paged(byte P) {
  16.    return PC&0xf800 | (Arg[0]&0xe0) << 3 | P;
  17. }
  18.  
  19. word Relative(byte R) {
  20.    return PC + (signed char)R;
  21. }
  22.  
  23. word Entries[0x100], *EP = Entries;
  24.  
  25. void PUSH(word Address) {
  26.    byte B = Ref[Address]&LINKS;
  27.    if (Ref[Address]&ARG) {
  28.       fprintf(stderr, "Entry into ARG at %04x.\n", PC); return;
  29.    }
  30.    if (++B <= LINKS) Ref[Address] = Ref[Address]&~LINKS | B;
  31.    if (Ref[Address]&ENTRY) return;
  32.    Ref[Address] |= ENTRY;
  33.    if (Ref[Address]&OP) return;
  34.    if (EP - Entries == 0x100) {
  35.       fprintf(stderr, "Too many entries, PC = %04x.\n", PC); exit(1);
  36.    }
  37.    *EP++ = Address;
  38. }
  39.  
  40. byte Xs[0x100] = {
  41.  1, 14, 15,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  42.  7,  6,  7,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  43.  7, 14,  9,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  44.  7,  6,  9,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  45.  6, 14,  2,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  46.  6,  6,  2,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  47.  6, 14,  2,  3,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  48.  6,  6,  2, 25,  2,  3,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
  49. 14, 14,  2,  1,  1,  3,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
  50.  3,  6,  2,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  51.  2, 14,  2,  1,  1,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
  52.  2,  6,  2,  1,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
  53.  2, 14,  2,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  54.  2,  6,  2,  1,  1,  7,  1,  1,  6,  6,  6,  6,  6,  6,  6,  6,
  55.  1, 14,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
  56.  1,  6,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1
  57. };
  58.  
  59. char *Ns[0x100] = {
  60. "nop",           "ajmp %P",  "ljmp %L",     "rr A",
  61.    "inc A",          "inc %D",         "inc %i",          "inc %i",
  62.    "inc %n",          "inc %n",          "inc %n",          "inc %n",
  63.    "inc %n",          "inc %n",          "inc %n",          "inc %n",
  64. "jbc %B, %R",    "acall %P", "lcall %L",    "rrc A",
  65.    "dec A",          "dec %D",         "dec %i",          "dec %i",
  66.    "dec %n",          "dec %n",          "dec %n",          "dec %n",
  67.    "dec %n",          "dec %n",          "dec %n",          "dec %n",
  68. "jb %B, %R",     "ajmp %P",  "ret",         "rl A",
  69.    "add A, %I",      "add A, %D",      "add A, %i",       "add A, %i",
  70.    "add A, %n",       "add A, %n",       "add A, %n",       "add A, %n",
  71.    "add A, %n",       "add A, %n",       "add A, %n",       "add A, %n",
  72. "jnb %B, %R",    "acall %P", "reti",        "rlc A",
  73.    "addc A, %I",     "addc A, %D",     "addc A, %i",      "addc A, %i",
  74.    "addc A, %n",      "addc A, %n",      "addc A, %n",      "addc A, %n",
  75.    "addc A, %n",      "addc A, %n",      "addc A, %n",      "addc A, %n",
  76. "jc %R",         "ajmp %P",  "orl %D, A",   "orl %D, %I",
  77.    "orl A, %I",      "orl A, %D",      "orl A, %i",       "orl A, %i",
  78.    "orl A, %n",       "orl A, %n",       "orl A, %n",       "orl A, %n",
  79.    "orl A, %n",       "orl A, %n",       "orl A, %n",       "orl A, %n",
  80. "jnc %R",        "acall %P", "anl %D, A",   "anl %D, %I",
  81.    "anl A, %I",      "anl A, %D",      "anl A, %i",       "anl A, %i",
  82.    "anl A, %n",       "anl A, %n",       "anl A, %n",       "anl A, %n",
  83.    "anl A, %n",       "anl A, %n",       "anl A, %n",       "anl A, %n",
  84. "jz %R",         "ajmp %P",  "xrl %D, A",   "xrl %D, %I",
  85.    "xrl A, %I",      "xrl A, %D",      "xrl A, %i",       "xrl A, %i",
  86.    "xrl A, %n",       "xrl A, %n",       "xrl A, %n",       "xrl A, %n",
  87.    "xrl A, %n",       "xrl A, %n",       "xrl A, %n",       "xrl A, %n",
  88. "jnz %R",        "acall %P", "orl C, %B",   "jmp @A+DPTR",
  89.    "mov A, %I",      "mov %D, %I",     "mov %i, %I",      "mov %i, %I",
  90.    "mov %n, %I",      "mov %n, %I",      "mov %n, %I",      "mov %n, %I",
  91.    "mov %n, %I",      "mov %n, %I",      "mov %n, %I",      "mov %n, %I",
  92. "sjmp %R",       "ajmp %P",  "anl C, %B",   "movc A, @A+PC",
  93.    "div AB",         "mov %2D, %1D",   "mov %D, %i",      "mov %D, %i",
  94.    "mov %D, %n",      "mov %D, %n",      "mov %D, %n",      "mov %D, %n",
  95.    "mov %D, %n",      "mov %D, %n",      "mov %D, %n",      "mov %D, %n",
  96. "mov DPTR, %W",  "acall %P", "mov %B, C",   "movc A, @A+DPTR",
  97.    "subb A, %I",     "subb A, %D",     "subb A, %i",      "subb A, %i",
  98.    "subb A, %n",      "subb A, %n",      "subb A, %n",      "subb A, %n",
  99.    "subb A, %n",      "subb A, %n",      "subb A, %n",      "subb A, %n",
  100. "orl C, /%B",    "ajmp %P",  "mov C, %B",   "inc DPTR",
  101.    "mul AB",         "ERROR",          "mov %i, %D",      "mov %i, %D",
  102.    "mov %n, %D",      "mov %n, %D",      "mov %n, %D",      "mov %n, %D",
  103.    "mov %n, %D",      "mov %n, %D",      "mov %n, %D",      "mov %n, %D",
  104. "anl C, /%B",    "acall %P", "cpl %B",      "cpl C",
  105.    "cjne A, %I, %R", "cjne A, %D, %R", "cjne %i, %I, %R", "cjne %i, %I, %R",
  106.    "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R",
  107.    "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R",
  108. "push %D",       "ajmp %P",  "clr %B",      "clr C",
  109.    "swap A",         "xch A, %D",      "xch A, %i",       "xch A, %i",
  110.    "xch A, %n",       "xch A, %n",       "xch A, %n",       "xch A, %n",
  111.    "xch A, %n",       "xch A, %n",       "xch A, %n",       "xch A, %n",
  112. "pop %D",        "acall %P", "setb %B",     "setb C",
  113.    "da A",           "djnz %D, %R",    "xchd A, %i",      "xchd A, %i",
  114.    "djnz %n, %R",     "djnz %n, %R",     "djnz %n, %R",     "djnz %n, %R",
  115.    "djnz %n, %R",     "djnz %n, %R",     "djnz %n, %R",     "djnz %n, %R",
  116. "movx A, @DPTR", "ajmp %P",  "movx A, @R0", "movx A, @R1",
  117.    "clr A",          "mov A, %D",      "mov A, %i",       "mov A, %i",
  118.    "mov A, %n",       "mov A, %n",       "mov A, %n",       "mov A, %n",
  119.    "mov A, %n",       "mov A, %n",       "mov A, %n",       "mov A, %n",
  120. "movx @DPTR, A", "acall %P", "movx @R0, A", "movx @R1, A",
  121.    "cpl A",          "mov %D, A",      "mov %i, A",       "mov %i, A",
  122.    "mov %n, A",       "mov %n, A",       "mov %n, A",       "mov %n, A",
  123.    "mov %n, A",       "mov %n, A",       "mov %n, A",       "mov %n, A"
  124. };
  125.  
  126. void PrintByte(byte B) {
  127.    if (B >= 0xa0) putchar('0');
  128.    printf("%02xh", B);
  129. }
  130.  
  131. void PrintWord(word W) {
  132.    if (W >= 0xa000) putchar('0');
  133.    printf("%04xh", W);
  134. }
  135.  
  136. char *SFRs[0x80] = {
  137.   "P0", "SP", "DPL", "DPH", 0, 0, 0, "PCON",
  138.   "TCON", "TMOD", "TL0", "TL1", "TH0", "TH1", 0, 0,
  139.   "P1", 0, 0, 0, 0, 0, 0, 0, "SCON", "SBUF", 0, 0, 0, 0, 0, 0,
  140.   "P2", 0, 0, 0, 0, 0, 0, 0, "IE", 0, 0, 0, 0, 0, 0, 0,
  141.   "P3", 0, 0, 0, 0, 0, 0, 0, "IP", 0, 0, 0, 0, 0, 0, 0,
  142.   0, 0, 0, 0, 0, 0, 0, 0, "T2CON", 0, "RCAP2L", "RCAP2H", "TL2", "TH2", 0, 0,
  143.   "PSW", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  144.   "ACC", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  145.   "B", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  146. };
  147.  
  148. void PrintData(byte D) { /* THIS ASSUMES THE 8052 */
  149.    if (!Generating) return;
  150.    if (D < 0x80 || SFRs[D - 0x80] == 0) { PrintByte(D); return; }
  151.    printf(SFRs[D - 0x80]);
  152. }
  153.  
  154. char *Bits[0x80] = {
  155.    0, 0, 0, 0, 0, 0, 0, 0,
  156.    "IT0", "IE0", "IT1", "IE1", "TR0", "TF0", "TR1", "TF1",
  157.    "T2", "T2EX", 0, 0, 0, 0, 0, 0,
  158.    "RI", "TI", "RB8", "TB8", "REN", "SM2", "SM1", "SM0",
  159.    0, 0, 0, 0, 0, 0, 0, 0,
  160.    "EX0", "ET0", "EX1", "ET1", "ES", "ET2", 0, "EA",
  161.    "RXD", "TXD", "INT0", "INT1", "T0", "T1", "WR", "RD",
  162.    "PX0", "PT0", "PX1", "PT1", "PS", "PT2", 0, 0,
  163.    0, 0, 0, 0, 0, 0, 0, 0,
  164.    "CP_RL2", "C_T2", "TR2", "EXEN2", "TCLK", "RCLK", "EXF2", "TF2",
  165.    "P", 0, "OV", "RS0", "RS1", "F0", "AC", "CY", 0, 0, 0, 0, 0, 0, 0, 0,
  166.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  167.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  168. };
  169.  
  170. void PrintBit(byte B) {
  171.    byte Byte, Bit;
  172.    if (!Generating) return;
  173.    if (B < 0x80) { PrintByte(B); return; }
  174.    B -= 0x80;
  175.    if (Bits[B] != 0) { printf(Bits[B]); return; }
  176.    Byte = B&0x78; Bit = B&0x07;
  177.    if (SFRs[Byte] != 0) { printf("%s.%1x", SFRs[Byte], Bit); return; }
  178.    PrintByte((byte)(B + 0x80));
  179. }
  180.  
  181. void PrintImmByte(byte B) {
  182.    if (!Generating) return;
  183.    putchar('#'); PrintByte(B);
  184. }
  185.  
  186. void PrintImmWord(word W) {
  187.    if (!Generating) return;
  188.    putchar('#'); PrintWord(W);
  189. }
  190.  
  191. byte CheckSum; word HighAddr;
  192.  
  193. byte Nib(int X) {
  194.    if (X >= '0' && X <= '9') return ((byte)(X - '0'));
  195.    if (X >= 'a' && X <= 'f') return ((byte)(X - 'a' + 10));
  196.    if (X >= 'A' && X <= 'F') return ((byte)(X - 'A' + 10));
  197.    fprintf(stderr, "Bad hexadecimal digit in input.\n");
  198.    exit(1);
  199. }
  200.  
  201. byte GetHex(void) {
  202.    int A, B; byte Bt;
  203.    A = getchar(); B = getchar();
  204.    if (A == EOF || B == EOF) {
  205.       fprintf(stderr, "Unexpected EOF.\n"); exit(1);
  206.    }
  207.    Bt = Nib(A) << 4 | Nib(B);
  208.    CheckSum = (CheckSum + Bt)&0xff; return Bt;
  209. }
  210.  
  211. word GetWord(void) {
  212.    word A, B;
  213.    A = GetHex(); B = GetHex();
  214.    return (A << 8) | B;
  215. }
  216.  
  217. void HexLoad(void) {
  218.    int Ch, I;
  219.    byte Size, Mark, CheckSum; word Addr;
  220.    byte Buffer[0x10];
  221.    HighAddr = 0;
  222.    while (1) {
  223.       do {
  224.          Ch = getchar();
  225.          if (Ch == EOF) { fprintf(stderr, "Unexpected EOF.\n"); exit(1); }
  226.       } while (Ch != ':');
  227.       CheckSum = 0;
  228.       Size = GetHex(); Addr = GetWord(); Mark = GetHex();
  229.       for (I = 0; I < Size; I++) Buffer[I] = GetHex();
  230.       (void)GetHex();
  231.       if (CheckSum != 0) {
  232.          fprintf(stderr, "Bad checksum.\n"); exit(1);
  233.       }
  234.       if (Mark) break;
  235.       if (Addr >= 0x4000 - Size) {
  236.          printf("Address out of range 0 - 4000h in input.\n"); exit(0);
  237.       }
  238.       for (I = 0; I < Size; I++, Addr++) Hex[Addr] = Buffer[I], Ref[Addr] = 0;
  239.       if (Addr > HighAddr) HighAddr = Addr;
  240.       (void)getchar();
  241.    }
  242. }
  243.  
  244. #define IN_RANGE(A) ((A) >= 0x0000 && (A) < HighAddr)
  245.  
  246. word Address;
  247. void PutLabel(word PC) {
  248.    byte B;
  249.    if (!Generating) Address = PC;
  250.    else {
  251.       if (PC >= 0x4000) { PrintWord(PC); return; }
  252.       B = (Ref[PC]&LINKS) + 'A';
  253.       printf("%c%04x", B, PC);
  254.    }
  255. }
  256.  
  257. void MakeOp(char *S) {
  258.    int A; byte B;
  259.    for (A = 1; *S != '\0'; S++) {
  260.       if (*S != '%') {
  261.          if (Generating) putchar(*S);
  262.          continue;
  263.       }
  264.       S++;
  265.       if (*S >= '0' && *S <= '2') A = *S++ - '0';
  266.       switch (*S) {
  267.          case 'L': B = Arg[A++]; PutLabel(B << 8 | Arg[A++]); break;
  268.          case 'P': PutLabel(Paged(Arg[A++])); break;
  269.          case 'R': PutLabel(Relative(Arg[A++])); break;
  270.          case 'D': PrintData(Arg[A++]); break;
  271.          case 'B': PrintBit(Arg[A++]); break;
  272.          case 'I': PrintImmByte(Arg[A++]); break;
  273.          case 'W': B = Arg[A++]; PrintImmWord(B << 8 | Arg[A++]); break;
  274.          case 'i': if (Generating) printf("@R%1x", Arg[0]&1); break;
  275.          case 'n': if (Generating) printf("R%1x", Arg[0]&7); break;
  276.          default:
  277.             fprintf(stderr, "Bad format string, PC = %04x.\n", PC);
  278.          exit(1);
  279.       }
  280.    }
  281.    if (Generating) putchar('\n');
  282.    else if (!IN_RANGE(Address)) printf("REF: %04x\n", Address);
  283.    else PUSH(Address);
  284. }
  285.  
  286. int Disassemble(void) {
  287.    byte B; byte Mode; char *Name; int I;
  288.    if (Ref[PC]&ARG) {
  289.       fprintf(stderr, "OP into ARG at %04x.\n", PC++); return 1;
  290.    }
  291.    if (Generating) {
  292.       if (Ref[PC]&ENTRY) { PutLabel(PC); printf(":\n"); }
  293.    } else {
  294.       if (Ref[PC]&OP) { PC++; return 1; }
  295.       Ref[PC] |= OP;
  296.    }
  297.    Arg[0] = B = Hex[PC++];
  298.    Mode = Xs[B]; Name = Ns[B];
  299.    for (I = 1; I < (Mode&3); I++) {
  300.       if (Ref[PC]&OP) {
  301.          fprintf(stderr, "ARG into OP at %04x.\n", PC); return 1;
  302.       }
  303.       if (!Generating) {
  304.          if (Ref[PC]&ARG) {
  305.             fprintf(stderr, "ARG into ARG at %04x.\n", PC); return 1;
  306.          }
  307.          Ref[PC] |= ARG;
  308.       }
  309.       Arg[I] = Hex[PC++];
  310.    }
  311.    if (Generating) {
  312.       if (!(Mode&8)) printf("   ");
  313.       MakeOp(Name);
  314.    } else {
  315.       if (Mode&4) MakeOp(Name);
  316.       if (Mode&0x10) {
  317.          printf("Indirect jump at %04x\n", PC - (Mode&3));
  318.       }
  319.    }
  320.    return (!Generating && (Mode&8) || Generating && !Ref[PC]);
  321. }
  322.  
  323. void PCHAR(byte B) { putchar((B < 0x20 || B >= 0x7f)? ' ': B); }
  324.  
  325. int Ended; FILE *EntryF;
  326.  
  327. byte fGetHex(void) {
  328.    int A, B;
  329.    if (Ended) return 0;
  330.    A = fgetc(EntryF); B = fgetc(EntryF);
  331.    if (A == EOF || B == EOF) { Ended = 1; return 0; }
  332.    return ((byte)(Nib(A) << 4 | Nib(B)));
  333. }
  334.  
  335. word fGetWord(void) {
  336.    word A, B;
  337.    A = fGetHex(); B = fGetHex();
  338.    (void)fgetc(EntryF);
  339.    if (Ended) return 0;
  340.    return (A << 8) | B;
  341. }
  342.  
  343. void main(void) {
  344.    word /* *E,*/ W;
  345.    HexLoad();
  346. fprintf(stderr, "First pass\n");
  347.    Generating = 0;
  348.    EntryF = fopen("entries", "r");
  349.    if (EntryF == NULL) {
  350.       fprintf(stderr, "No entry points listed.\n"); exit(1);
  351.    }
  352.    for (Ended = 0, EP = Entries; !Ended; ) {
  353.       W = fGetWord(); if (!Ended) PUSH(W);
  354.    }
  355.    while (EP > Entries) {
  356.       PC = *--EP;
  357.       while (!Disassemble());
  358.    }
  359. fprintf(stderr, "Second pass\n");
  360.    Generating = 1;
  361.    if (Ref[0]) printf("org 0\n");
  362.    for (PC = 0x00; IN_RANGE(PC); ) {
  363.       byte F, Buf[16];
  364.       if (!Ref[PC]) {
  365.          printf("DATA AT "); PrintWord(PC); putchar('\n');
  366.          for (F = 0; !Ref[PC] && IN_RANGE(PC); PC++) {
  367.             Buf[F++] = Hex[PC];
  368.             if (F == 16) {
  369.                for (F = 0; F < 16; F++) {
  370.                   printf("%2x", Buf[F]);
  371.                   if (F < 15) putchar(' '); else putchar('|');
  372.                }
  373.                for (F = 0; F < 16; F++) PCHAR(Buf[F]);
  374.                putchar('|'); putchar('\n');
  375.                F = 0;
  376.             }
  377.          }
  378.          if (F > 0) {
  379.             byte F1;
  380.             for (F1 = 0; F1 < F; F1++) printf("%2x ", Buf[F1]);
  381.             for (; F1 < 16; F1++) {
  382.                Buf[F1] = 0;
  383.                printf("  "); if (F1 < 15) putchar(' '); else putchar('|');
  384.             }
  385.             for (F = 0; F < 16; F++) PCHAR(Buf[F]);
  386.             putchar('|'); putchar('\n');
  387.          }
  388.          if (!IN_RANGE(PC)) break;
  389.          printf("org "); PrintWord(PC); putchar('\n');
  390.       }
  391.       while (!Disassemble());
  392.    }
  393. }
  394.